<?php

	// +----------------------------------------------------------------------
	// | 公众号对接
	// +----------------------------------------------------------------------
	// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
	// +----------------------------------------------------------------------
	// | Author: 微尘 <yicmf@qq.com>
	// +----------------------------------------------------------------------

	namespace app\controller\api\notify;

    use EasyWeChat\OpenWork\Application;
	use app\event\ucenter\User as UserEvent;
    use app\wechat\model\WechatAccount as WechatAccountModel;
    use app\wechat\model\WechatFans as WechatFansModel;
    use app\wechat\model\WechatMenu as WechatMenuModel;
    use app\wechat\model\WechatMsg as WechatMsgModel;
    use app\wechat\model\WechatReply as WechatReplyModel;
    use think\App;
    use think\Exception;
    use think\facade\Event;
    use think\facade\Log;
    use wechat\mch\Pay as WechatMchPay;
    use wechat\message\Image as WechatMsgImage;
    use wechat\message\News as WechatMsgNews;
    use wechat\message\Text as WechatMsgText;
    use wechat\official_account\Media as WechatServerMedia;
    use wechat\official_account\Oauth as WechatOauth;
    use wechat\official_account\Server as ServerOfficialAccount;
    use wechat\official_account\Template;
    use wechat\official_account\Template as TemplateOfficial;
    use wechat\official_account\User as UserOfficial;

    class WechatOfficial
	{

		/**
		 * 应用实例
		 * @var App
		 */
		protected $app;

		/**
		 * @var WechatFansModel
		 */
		private $fans = null;

		/**
		 * Request实例
		 * @var \think\Request
		 */
		protected $request;

		/**
		 * 留言模型
		 * @var WechatMsgModel
		 */
		private $leaveWord = null;

		/**
		 * 留言模型
		 * @var WechatAccountModel
		 */
		private $account = null;
		private $word;
		/**
		 * 用户openid
		 */
		private $openid = null;
		/**
		 * @var ServerOfficialAccount
		 */
		private $service = null;


		/**
		 * 构造方法
		 * @access public
		 */
		public function __construct(App $app = null)
		{
            $this->app     = $app;
            $this->request = $this->app->request;
            $this->account['token'] = 'yunfuye';
            $this->account['encoding_aes_key'] = 'BkrUUPz9IgfERTRXmwiIf0RSir4ONBku64EufsZ9EE2';
            $this->account['app_secret'] = 'xaF0qtSv0eruwgQEzeyWoQIeNL_fUQXTy2ciKpUFzME';
            $this->account['app_id'] = '1000010';
			$service = new ServerOfficialAccount();
			$this->service = $service->initAccount($this->account);
		}

        public function server()
        {
            $log = config('log');
            $log['default'] = 'wechat';
            config($log, 'log');
            include_once app()->getRootPath() . 'extend/weworkapi/callback/WXBizMsgCrypt.php';

// 假设企业号在公众平台上设置的参数如下
            $encodingAesKey = "BkrUUPz9IgfERTRXmwiIf0RSir4ONBku64EufsZ9EE2";
            $token = "yunfuye";
            $corpId = "wwc7417afd6b5e73b6";

            $wxcpt = new \WXBizMsgCrypt($token, $encodingAesKey, $corpId);
            if ($this->request->param('echostr'))
            {
                $sVerifyMsgSig = $this->request->param('msg_signature');
                $sVerifyTimeStamp =  $this->request->param('timestamp');
                $sVerifyNonce =  $this->request->param('nonce');
                $sVerifyEchoStr =  $this->request->param('echostr');
                $sEchoStr = "";
                $errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
                if ($errCode == 0) {
                    return $sEchoStr;
                } else {
                    return 'err';
                }
            }else{
                /*
          ------------使用示例二：对用户回复的消息解密---------------
          用户回复消息或者点击事件响应时，企业会收到回调消息，此消息是经过公众平台加密之后的密文以post形式发送给企业，密文格式请参考官方文档
          假设企业收到公众平台的回调消息如下：
          POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6&timestamp=1409659813&nonce=1372623149 HTTP/1.1
          Host: qy.weixin.qq.com
          Content-Length: 613
          <xml>
          <ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt>
          <AgentID><![CDATA[218]]></AgentID>
          </xml>
          企业收到post请求之后应该
          1.解析出url上的参数，包括消息体签名(msg_signature)，时间戳(timestamp)以及随机数字串(nonce)
          2.验证消息体签名的正确性。
          3.将post请求的数据进行xml解析，并将<Encrypt>标签的内容进行解密，解密出来的明文即是用户回复消息的明文，明文格式请参考官方文档
          第2，3步可以用公众平台提供的库函数DecryptMsg来实现。
          */

                $sReqMsgSig = $this->request->param('msg_signature');
                $sReqTimeStamp =  $this->request->param('timestamp');
                $sReqNonce =  $this->request->param('nonce');

                $sRespData=file_get_contents("php://input");
// post请求的密文数据
// $sReqData = HttpUtils.PostData();
//                $sReqData = "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt><AgentID><![CDATA[218]]></AgentID></xml>";
                $sMsg = "";  // 解析之后的明文
                $errCode = $wxcpt->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sRespData, $sMsg);
                Log::write($errCode);
                Log::write($sMsg);
                if ($errCode == 0) {
                    // 解密成功，sMsg即为xml格式的明文
                    var_dump($sMsg);
                    // TODO: 对明文的处理
                    /*
                    "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName>
                <FromUserName><![CDATA[mycreate]]></FromUserName>
                <CreateTime>1409659813</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[hello]]></Content>
                <MsgId>4561255354251345929</MsgId>
                <AgentID>218</AgentID>
                </xml>"
                */
                } else {
                    print("ERR: " . $errCode . "\n\n");
                    //exit(-1);
                }

                /*
                ------------使用示例三：企业回复用户消息的加密---------------
                企业被动回复用户的消息也需要进行加密，并且拼接成密文格式的xml串。
                假设企业需要回复用户的明文如下：
                <xml>
                <ToUserName><![CDATA[mycreate]]></ToUserName>
                <FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName>
                <CreateTime>1348831860</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[this is a test]]></Content>
                <MsgId>1234567890123456</MsgId>
                <AgentID>128</AgentID>
                </xml>

                为了将此段明文回复给用户，企业应：
                1.自己生成时间时间戳(timestamp),随机数字串(nonce)以便生成消息体签名，也可以直接用从公众平台的post url上解析出的对应值。
                2.将明文加密得到密文。
                3.用密文，步骤1生成的timestamp,nonce和企业在公众平台设定的token生成消息体签名。
                4.将密文，消息体签名，时间戳，随机数字串拼接成xml格式的字符串，发送给企业号。
                以上2，3，4步可以用公众平台提供的库函数EncryptMsg来实现。
                */

//                $sRespData=file_get_contents("php://input");
//// 需要发送的明文
////                $sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";
//                $sEncryptMsg = ""; //xml格式的密文
//                $errCode = $wxcpt->EncryptMsg($sRespData, $sReqTimeStamp, $sReqNonce, $sEncryptMsg);
//
//                $data=simplexml_load_string($sEchoStr,'SimpleXMLElement', LIBXML_NOCDATA);
//                $data = json_encode($data);
//                $data = json_decode($data,true);
//
//
//                if ($errCode == 0) {
//                    Log::write($sRespData);
//                    return $sEncryptMsg;
//                    // TODO:
//                    // 加密成功，企业需要将加密之后的sEncryptMsg返回
//                    // HttpUtils.SetResponce($sEncryptMsg);  //回复加密之后的密文
//                } else {
//                    return $errCode;
//                }

                return'ok';
            }



//
//            $config = [
//                'corp_id' => 'wwc7417afd6b5e73b6',
//                'provider_secret' => 'xaF0qtSv0eruwgQEzeyWoQIeNL_fUQXTy2ciKpUFzME',
//                'token' => 'yunfuye',
//                'aes_key' => 'BkrUUPz9IgfERTRXmwiIf0RSir4ONBku64EufsZ9EE2', // 明文模式请勿填写 EncodingAESKey
//
//                /**
//                 * 接口请求相关配置，超时时间等，具体可用参数请参考：
//                 * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php
//                 */
//                'http' => [
//                    'throw'  => true, // 状态码非 200、300 时是否抛出异常，默认为开启
//                    'timeout' => 5.0,
//                    // 'base_uri' => 'https://qyapi.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri
//
//                    'retry' => true, // 使用默认重试配置
//                    //  'retry' => [
//                    //      // 仅以下状态码重试
//                    //      'status_codes' => [429, 500]
//                    //       // 最大重试次数
//                    //      'max_retries' => 3,
//                    //      // 请求间隔 (毫秒)
//                    //      'delay' => 1000,
//                    //      // 如果设置，每次重试的等待时间都会增加这个系数
//                    //      // (例如. 首次:1000ms; 第二次: 3 * 1000ms; etc.)
//                    //      'multiplier' => 3
//                    //  ],
//                ],
//            ];
//
//            $app = new Application($config);
//            $server = $app->getServer();
//            $response = $server->serve();
//            dump($server);
//            dump($response);
////            dump($response->getBody()->getContents());
//
//            exit();
//            return $app->getServer();
        }
        function checkSignature()
        {
            $signature = $_GET["msg_signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];
            $token = "yunfuye";

            $tmpArr = array($token, $timestamp, $nonce);
            sort($tmpArr, SORT_STRING);
            dump($tmpArr);
            $tmpStr = implode($tmpArr);
            $tmpStr = sha1($tmpStr);

            dump($tmpStr);
            dump($signature);
            if ($tmpStr == $signature) {
                return true;
            } else {
                return false;
            }
        }

        public function pay()
        {
            $param['out_trade_no'] = $this->pay['pay_sn'];
            $param['trade_type'] = 'APP';
            $param['notify_url'] = url('pay/Wechat/notify', '', true, true);
            $param['total_fee'] = $this->pay['total_amount'] * 100;
            //  $param['total_fee'] = 1;
            $param['attach'] = $this->pay['type'];
            $param['detail'] = '';// 保留
            $param['body'] = '商品支付';
            $param['device_info'] = 'app';
            $WechatMchPay = new WechatMchPay();
            $pay_result = $WechatMchPay->unifiedorder($param);

        }
        public function fuwu()
        {


            if($this->checkSignature()) {
                $echostr = $_GET['echostr'];
                return  $echostr;
            }else{
                return 's';
            }
//
////            $signature = $_GET["signature"];
////            $timestamp = $_GET["timestamp"];
////            $nonce = $_GET["nonce"];
////
//
//            $echostr = $_GET['echostr'];
//            echo $echostr;
//
//
//            $token = 'yunfuye';
////            $tmpArr = array($token, $timestamp, $nonce);
////            sort($tmpArr, SORT_STRING);
////            $tmpStr = implode( $tmpArr );
////            $tmpStr = sha1( $tmpStr );
//
//            return $token;
//            if( $tmpStr == $signature ){
//                return true;
//            }else{
//                return false;
//            }
//            return 'ok';
        }

        public function payOrder($order)
        {
            $oa = new Template();
            $oa->initAccount($this->account);
//            $WechatTemplate = WechatTemplateModel::where('wechat_no', 'OPENTM401627381')->where('status', 1)->find();
            $data = [
                'amount7' => ['value' => $order['amount'], 'color' => '#000000'],
                'character_string6' => ['value' => $order['sn'], 'color' => '#000000'],
                'time5' => ['value' => time_format(), 'color' => '#000000'],
                'phone_number4' => ['value' =>  $order['user']['username'], 'color' => '#000000'],
                //                'keyword1'=> ['value'=>$auth['idcard_name'], 'color'=>'#000000'],
                //                'keyword2'=> ['value'=>time_format(), 'color'=>'#000000'],
                'thing8' => ['value' => '如果有疑问', 'color' => '#000000'],
            ];

            $re = $oa->send('oAAIg6zwyPLf6jeOUBvWazwzA2qU', 'rYCxbRngE4XXD_D4Lhg25n9jM9psopW6rJXZtVlU-Es', $data, '');
            $re = $oa->send('oAAIg61CfAjbBmIPUojwc87FsQBA', 'rYCxbRngE4XXD_D4Lhg25n9jM9psopW6rJXZtVlU-Es', $data, '');
            $re = $oa->send('oAAIg6w_C0wy7_rmcb3VahTohD6s', 'rYCxbRngE4XXD_D4Lhg25n9jM9psopW6rJXZtVlU-Es', $data, '');
        }

		public function test()
		{

            $oa = new Template();
            $oa->initAccount($this->account);
//            $WechatTemplate = WechatTemplateModel::where('wechat_no', 'OPENTM401627381')->where('status', 1)->find();
            $data = [
                'amount7' => ['value' => '11.33', 'color' => '#000000'],
                'character_string6' => ['value' => time(), 'color' => '#000000'],
                'time5' => ['value' => time_format(), 'color' => '#000000'],
                'phone_number4' => ['value' => '13033331111', 'color' => '#000000'],
                //                'keyword1'=> ['value'=>$auth['idcard_name'], 'color'=>'#000000'],
                //                'keyword2'=> ['value'=>time_format(), 'color'=>'#000000'],
                'thing8' => ['value' => '如果有疑问', 'color' => '#000000'],
            ];

//            订单金额
//{{amount7.DATA}}
//订单编号
//{{character_string6.DATA}}
//下单时间
//{{time5.DATA}}
//联系电话
//{{phone_number4.DATA}}
//客户名称
//{{thing8.DATA}}
            $re = $oa->send('oAAIg6w_C0wy7_rmcb3VahTohD6s', 'rYCxbRngE4XXD_D4Lhg25n9jM9psopW6rJXZtVlU-Es', $data, '');
            //

            dump($re);
//			$oa = new TemplateOfficial();
            $UserOfficial = new Template();
            $UserOfficial->initAccount($this->account);
            $user = $UserOfficial->getIndustry();//
//            $user = $UserOfficial->setIndustry(1,2);
            dump($user);
            exit();
//			$oa = new TemplateOfficial();
            $UserOfficial = new UserOfficial();
            $UserOfficial->initAccount($this->account);
            $user = $UserOfficial->userInfo('oAAIg6w_C0wy7_rmcb3VahTohD6s');
            dump($user);
            exit();
//            $WechatTemplate = WechatTemplateModel::where('wechat_no', 'OPENTM401627381')->where('status', 1)->find();
			$data = [
				'first' => ['value' => '成功', 'color' => '#000000'],
				'number' => ['value' => '1', 'color' => '#000000'],
				//                'keyword1'=> ['value'=>$auth['idcard_name'], 'color'=>'#000000'],
				//                'keyword2'=> ['value'=>time_format(), 'color'=>'#000000'],
				'remark' => ['value' => '如果有疑问，请联系客服！', 'color' => '#000000'],
			];
			//            $oa->send('o7ldnuMTe7Ifj1yFa7iW9aP9d5lw', $WechatTemplate['template_id'],
			//                url('mobile/User/auth',[],true,true),
			//                $param);
			$re = $oa->send('oAAIg6w_C0wy7_rmcb3VahTohD6s', '0sL1x8Gk3bl9AN3VDM3ONPN4mXuVAlUVClkmb3etSwI', $data, '');
			dump($re);
		}
		public function h5()
		{

            $oauth = new WechatOauth();


            $oauth->initAccount($this->account);

            $token = $oauth->getCodeAccessToken($this->request->param('code'));
            if (!isset($token['errcode']))
            {
                $user = $oauth->userInfo($token['openid'],$token['access_token']);

                if (count($user))
                {

                    $user_event = new UserEvent();
                    $param['channel'] = 'weixin';
                    $param['open_id'] = $token['openid'];
                    $param['avatar_url'] = $user['headimgurl'];
                    $param['nickname'] = $user['nickname'];
                    $param['sex'] = $user['sex'];
                    $data = $user_event->oauthLogin($param);
                    if ($data['code'] == 0)
                    {
                        // 成功登录
                        return redirect('https://web.yunfuye.com/#/pages/login/login?token=' . $data['data']['user']['token'].'&openid='.$token['openid']);
                    }elseif ($data['code'] == 10)
                    {
                        return redirect('https://web.yunfuye.com/#/pages/login/bind?openid='.$token['openid'],200);
                    }else{
                        return $data['message'];
                    }
                }else{
                    return '失败';
                }
            }else{
                return $token['errmsg'];
            }

//            dump($re);
//
//            array(5) {
//            ["access_token"] => string(110) "86_F1jfW5f7VAV2i1p3c-jq_6_lxyF6uTSkecXF53vpep-5G5NkhjVKBpthcZEz1noYw-v-B6-Ddk5jAprYb1xEeAfU18Ir5OpDeR2R4mdvThQ"
//            ["expires_in"] => int(7200)
//            ["refresh_token"] => string(110) "86_-nBq5Gnr3Qa2U5s6g8N2ui7BlBBk0AEkmEbadb-dOrTqpy5nwdJl-APPiqid50s7KSX4WluwVP__LPXYT2j9vgYwtQn7-NqDvuelyfbBlrI"
//            ["openid"] => string(28) "oAAIg6w_C0wy7_rmcb3VahTohD6s"
//            ["scope"] => string(15) "snsapi_userinfo"
//}

            exit();
//			$oa = new TemplateOfficial();
            $UserOfficial = new UserOfficial();
            $UserOfficial->initAccount($this->account);
            $user = $UserOfficial->userInfo('oAAIg6w_C0wy7_rmcb3VahTohD6s');
            dump($user);
            exit();
//            $WechatTemplate = WechatTemplateModel::where('wechat_no', 'OPENTM401627381')->where('status', 1)->find();
			$data = [
				'first' => ['value' => '成功', 'color' => '#000000'],
				'number' => ['value' => '1', 'color' => '#000000'],
				//                'keyword1'=> ['value'=>$auth['idcard_name'], 'color'=>'#000000'],
				//                'keyword2'=> ['value'=>time_format(), 'color'=>'#000000'],
				'remark' => ['value' => '如果有疑问，请联系客服！', 'color' => '#000000'],
			];
			//            $oa->send('o7ldnuMTe7Ifj1yFa7iW9aP9d5lw', $WechatTemplate['template_id'],
			//                url('mobile/User/auth',[],true,true),
			//                $param);
			$re = $oa->send('oAAIg6w_C0wy7_rmcb3VahTohD6s', '0sL1x8Gk3bl9AN3VDM3ONPN4mXuVAlUVClkmb3etSwI', $data, '');
			dump($re);
		}

		/**
		 * 微信消息入口
		 * @return bool|mixed|string
		 * @throws \Exception
		 * @author 微尘 <yicmf@qq.com>
		 */
		public function index()
		{
			try {
				$this->service->check();
				// 获取消息来源用户OPENID
				$this->openid = $this->service->getOpenid();
				// 获取并同步粉丝信息到数据库
				$this->_setFan(true);
				if ('event' == $this->service->getMsgType()) {
					$reply = $this->_event();
				} else {
					$reply = $this->_receive();
				}
				if (empty($reply)) {
					$reply = '服务器开小差了，请稍候再试';
				}
			} catch (Exception $e) {
				$reply = $e->getMessage();
			}
			$reply = $this->_replyConvert($reply);
			if ($reply == 'success') {
				return $reply;
			} else {
				return $this->service->reply($reply)->send();
			}
		}

		/**
		 * 消息处理
		 */
		protected function _receive()
		{
			$this->word['event'] = 'keys';
			// 分别执行对应类型的操作

			$method = '_receive' . ucwords($this->service->getMsgType());
			if (method_exists($this, $method)) {
				$reply = $this->$method();
			} else {
				$reply = $this->_receiveDefault();
			}
			if (!$reply) {
				$reply = $this->_keyReply($this->service->getMsgType(), $this->service->getContent());
			}
			return $reply;
		}

		/**
		 * 事件处理
		 */
		protected function _event()
		{
			$event = $this->service->getEvent();
			$this->word['event'] = strtolower($event['event']);
			switch (strtolower($event['event'])) {
				case 'subscribe': // 粉丝关注事件
					$this->_spread($event['key']);
					$reply = $this->_eventReply(strtolower($event['event']), $event['key']);
					break;
				case 'unsubscribe':// 粉丝取消关注
					$this->_setFan(false);
					$reply = 'success';
					break;
				case 'click': // 点击菜单事件
					$reply = $this->_eventClick($event['key']);
					break;
				case 'scancode_push':
				case 'scancode_waitmsg': // 扫码推事件
					$scanInfo = $this->service->getScanInfo();
					if (isset($scanInfo['ScanResult'])) {
						$this->word['content'] = $scanInfo['ScanResult'];
						$reply = $this->_eventReply(strtolower($event['event']), $scanInfo['ScanResult']);
					} else {
						$reply = 'success';
					}
					break;
				case 'scan':// 已经关注扫码
					if (!empty($event['key'])) {
						$this->_spread($event['key']);
						$reply = $this->_eventReply(strtolower($event['event']), $event['key']);
					} else {
						$reply = 'success';
					}
					break;
				default:
					$reply = $this->_eventReply(strtolower($event['event']), $event['key']);
			}
			return $reply;
		}

		/**
		 * 推荐好友扫码关注
		 * @param string $event
		 * @return mixed
		 */
		private function _spread($event)
		{
//			$key = preg_replace('|^.*?(\d+).*?$|', '$1', "{$event}");
//			// 检测推荐是否有效
//			$fans = Db::name('WechatFans')->where('id', $key)->find();
//			if (!is_array($fans) || !isset($fans['openid']) || $fans['openid'] === $this->openid) {
//				return false;
//			}
//			// 标识推荐关系
//			$data = ['spread_openid' => $fans['openid'], 'spread_at' => date('Y-m-d H:i:s')];
//			Db::name('WechatFans')->where("openid='{$this->openid}' and (spread_openid is null or spread_openid='')")->update($data);
		}

		/**
		 * 响应回复
		 * @param string $event
		 * @param string $content
		 * @return string|WechatReplyModel
		 */
		private function _eventReply($event, $content)
		{
			$this->word['event'] = $event;
			///完整匹配
			$reply = WechatReplyModel::where('main_event', $event)
				->where('keys', $content)->where('matching', 1)
				->order('sort ASC')->where('status', 1)->find();
			// 默认
			if (!$reply) {
				// 统一处理
				$reply = WechatReplyModel::where('main_event', 'all')->where('status', 1)->find();
			}
			return $reply;
		}

		/**
		 * 响应回复
		 * @param string $receive_type
		 * @param string $content
		 * @return string|WechatReplyModel
		 */
		private function _keyReply($receive_type, $content)
		{
			///完整匹配
			$reply = WechatReplyModel::where('main_event', 'keys')
				->where('keys', $content)
				->where('receive_type', $receive_type)
				->where('matching', 1)
				->order('sort ASC')->where('status', 1)->find();
			// 模糊匹配
			if (!$reply) {
				// 模糊一条消息
				$reply = WechatReplyModel::where('main_event', 'keys')
					->where('receive_type', $receive_type)
					->where('keys', 'like', '%' . $content . '%')
					->order('sort ASC')->where('matching', 0)
					->where('status', 1)->find();
			}
			// 默认
			if (!$reply) {
				// 统一处理
				$reply = WechatReplyModel::where('main_event', 'all')->where('status', 1)->find();
			}
			return $reply;
		}

		/**
		 * 解析回复消息
		 * @param $reply
		 * @return mixed|string|WechatMsgNews|WechatMsgText
		 * @throws Exception
		 */
		private function _replyConvert($reply)
		{

			if (is_object($reply)) {
				$this->word['wechat_reply_id'] = $reply['id'];
				$reply['times'] = $reply['times'] + 1;
				$reply->isAutoWriteTimestamp(false)->save();
				if ('text' == $reply['type']) {
					$content = $reply['content'];
					if ($reply['content'] && $reply['content'] !== 'success') {
						$content = new WechatMsgText();
						$content->setContent($reply['content']);
					}
				} elseif ('image' == $reply['type']) {
					// 回复图片
					$media = new WechatServerMedia();
					$media->initAccount($this->account);
					$result = $media->uploadImage($reply['image']['path']);
					if (is_array($result) && isset($result['errmsg'])) {
						Log::write($result['errmsg']);
						$content = new WechatMsgText();
						$content->setContent('系统故障，请稍候再试');
					} else {
						$content = new WechatMsgImage();
						$content->setMediaId($result['media_id']);

						$content = new WechatMsgNews();

						$content->setArticle('你好', 'miaoshu', $reply['image']['path'], $reply['image']['path']);

					}
				} elseif ('none' == $reply['type']) {
					// 回复图片
					$content = 'success';
				} elseif ('news' == $reply['type']) {
					// 回复图片
					$media = new WechatServerMedia();
					$media->initAccount($this->account);
					$result = $media->uploadImage($reply['image']['path']);
					if (is_array($result) && isset($result['errmsg'])) {
						Log::write($result['errmsg']);
						$content = new WechatMsgText();
						$content->setContent('系统故障，请稍候再试');
					} else {
						$content = new WechatMsgNews();
						$content->setArticle($reply['title'], $reply['description'], $reply['image']['url'], $reply['url']);
					}
				} else {
					$content = '未知';
				}
			} else {
				$content = $reply;
			}
			if (isset($this->word['content'])) {
				$this->word['type'] = $this->service->getMsgType();
				$this->word['reply'] = $content;
				$this->word['wechat_account_id'] = $this->account['id'];
				$this->word['wechat_fans_id'] = $this->fans['id'];
				$this->word['reply_time'] = time_format();
				WechatMsgModel::create($this->word);
			}
			return $content;
		}

		/**
		 * 接收文本消息
		 * @return mixed
		 * @author 微尘 <yicmf@qq.com>
		 * @datetime: 2020/5/11 14:29
		 */
		private function _receiveText()
		{
			$content = $this->service->getContent();
			$this->word['content'] = $content;
			return Event::trigger('wechat_receive_text', ['content' => $content, 'openid' => $this->openid], true);
		}


		/**
		 * 未定义事件处理
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveDefault()
		{
			$this->word['content'] = '未定义消息';
			return false;
		}

		/**
		 * 收到地址
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveLocation()
		{
			$message = $this->service->getReceive();
			$this->word['content'] = '粉丝发送地址：X' . $message['Location_X'] . '，Y：' . $message['Location_Y'] . '，详情：' . $message['Label'];
			$this->word['media_id'] = $message['Location_X'] . ',' . $message['Location_Y'];
			return false;
		}

		/**
		 * 收到图片
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveImage()
		{
			$this->word['content'] = '用户图片留言' . $this->service->getPicUrl();
			$this->word['media_id'] = $this->service->getMediaId();
			return false;
		}

		/**
		 * 收到语音
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveVoice()
		{
			$this->word['content'] = '用户语音留言' . $this->service->getMediaId();
			$this->word['media_id'] = $this->service->getMediaId();
			return false;
		}

		/**
		 * 收到视频
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveVideo()
		{
			$this->word['content'] = '用户视频留言' . $this->service->getMediaId();
			$this->word['media_id'] = $this->service->getMediaId();
			return false;
		}

		/**
		 * 收到视频
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _receiveLink()
		{
			$this->word['content'] = '用户链接消息' . $this->service->getUrl();
			return false;
		}

		/**
		 *设置当前用户
		 * @param bool $subscribe
		 */
		private function _setFan($subscribe = true)
		{
			$event = $this->service->getEvent();
			if (strtolower($event['event']) == 'unsubscribe') {
				$subscribe = false;
			}

			$fans = WechatFansModel::where('openid', $this->openid)->find();
			if ($subscribe) {
				$UserOfficial = new UserOfficial();
				$UserOfficial->initAccount($this->account);
				$user = $UserOfficial->userInfo($this->openid);
				if ($fans) {
					$this->fans = $fans;
				} else {
					$fans = [];
					$fans['nickname'] = $user['nickname'];
					$fans['city'] = $user['city'];
					$fans['city'] = $user['city'];
					$fans['openid'] = $user['openid'];
					$fans['province'] = $user['province'];
					$fans['country'] = $user['country'];
					$fans['subscribe_time'] = time_format($user['subscribe_time']);
					$fans['headimgurl'] = $user['headimgurl'];
					$fans['subscribe_scene'] = $user['subscribe_scene'];
					$fans['sex'] = $user['sex'];
					$fans['language'] = $user['language'];
					$fans['groupid'] = $user['groupid'];
					$fans['qr_scene'] = $user['qr_scene'];
					$fans['qr_scene_str'] = $user['qr_scene_str'];
					$fans['remark'] = $user['remark'];
					if (isset($user['unionid'])) {
						$fans['unionid'] = $user['unionid'];
					}
					$this->fans = WechatFansModel::create($fans);

				}
			} else {
				if ($fans) {
					$fans['unsubscribe_time'] = time_format();
					$fans['status'] = time_format();
					$fans->save();
				}
			}

		}


		/**
		 * 点击菜单
		 * @param $key
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _eventClick($key)
		{
			$menu = WechatMenuModel::where('id', $key)->find();
			if ($menu) {
				return $this->_eventReply('keys', $menu['key']);
			} else {
				Log::record('点击菜单，key：' . $key);
				return 'success';
			}
		}


		/**
		 * 默认事件
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _eventDefault($event)
		{
			Log::record('事件操作' . $event);
			return 'success';
		}

		/**
		 * 模板消息发送完毕，记录成功与失败
		 * @param $message
		 * @return string
		 * @author 微尘 <yicmf@qq.com>
		 */
		private function _eventTemplatesendjobfinish($message)
		{
			/**
			 * <xml>
			 * <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
			 * <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
			 * <CreateTime>1395658984</CreateTime>
			 * <MsgType><![CDATA[event]]></MsgType>
			 * <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
			 * <MsgID>200163840</MsgID>
			 * <Status><![CDATA[failed:user block]]></Status>
			 * </xml>
			 */
			return '模板消息发送完毕';
		}


	}
